package com.openstack.javasdk;

import com.alibaba.fastjson.JSONObject;
import org.openstack4j.api.Builders;
import org.openstack4j.api.OSClient.OSClientV3;
import org.openstack4j.model.common.ActionResponse;
import org.openstack4j.model.common.Identifier;
import org.openstack4j.model.compute.Flavor;
import org.openstack4j.model.compute.SimpleTenantUsage;
import org.openstack4j.model.network.*;
import org.openstack4j.model.network.builder.PortBuilder;
import org.openstack4j.openstack.OSFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value = "/neutron")
public class NeutronModule {

    //    You are not authorized to perform the requested action: identity:list_users.
    @GetMapping("/networks")
    public String all() {
        OSClientV3 os = Auth.getOS();
        List<? extends Network> networks = os.networking().network().list();
        return JSONObject.toJSONString(networks);
    }

    @GetMapping("/network")
    public String roleList(@RequestParam(value = "id") String id) {
        OSClientV3 os = Auth.getOS();
        Network network = os.networking().network().get(id);
        return JSONObject.toJSONString(network);
    }

    @GetMapping("/network/create")
    public String networkCreate() {
        OSClientV3 os = Auth.getOS();
        Network network = os.networking().network()
                .create(Builders.network().name("ext_network").tenantId("e0af27432aee4d74b88484c3779c3e42").build());
        return JSONObject.toJSONString(network);
    }

    @GetMapping("/network/delete")
    public String networkDelete(@RequestParam(value = "networkId") String networkId) {
        OSClientV3 os = Auth.getOS();
        ActionResponse networkId1 = os.networking().network().delete(networkId);
        return JSONObject.toJSONString(networkId1);
    }

    @GetMapping("/subnet/create")
    public String subnetCreate() {
        OSClientV3 os = Auth.getOS();
        Subnet subnet = os.networking().subnet().create(Builders.subnet()
                .name("MySubnet")
                .networkId("f885eaf3-2879-4147-b537-dd27fa3a345e")
                .tenantId("e0af27432aee4d74b88484c3779c3e42")
                .addPool("192.169.0.2", "192.169.0.254")
                .ipVersion(IPVersionType.V4)
                .cidr("192.169.0.0/24")
                .build());
        return JSONObject.toJSONString(subnet);
    }

    @GetMapping("/subnet/list")
    public String subnetList() {
        OSClientV3 os = Auth.getOS();
        List<? extends Subnet> subnets = os.networking().subnet().list();
        return JSONObject.toJSONString(subnets);
    }

    @GetMapping("/subnet/query")
    public String subnetQuery(@RequestParam( value = "subnetId") String subnetId) {
        OSClientV3 os = Auth.getOS();
        Subnet subnet = os.networking().subnet().get(subnetId);
        return JSONObject.toJSONString(subnet);
    }

    @GetMapping("/subnet/delete")
    public String subnetDelete(@RequestParam( value = "subnetId") String subnetId) {
        OSClientV3 os = Auth.getOS();
        ActionResponse subnetId1 = os.networking().subnet().delete(subnetId);
        return JSONObject.toJSONString(subnetId1);
    }

    @GetMapping("/port/list")
    public String portList() {
        OSClientV3 os = Auth.getOS();
        List<? extends Port> ports = os.networking().port().list();
        return JSONObject.toJSONString(ports);
    }

    @GetMapping("/port/create")
    public String portCreate() {
        OSClientV3 os = Auth.getOS();
        Port port = os.networking().port().create(Builders.port()
                .name("port-1")
                .networkId("f885eaf3-2879-4147-b537-dd27fa3a345e")
                .fixedIp("10.10.0.3", "9c722bad-9cb1-43f1-992a-f0893d61839d")
                .build());
        return JSONObject.toJSONString(port);
    }

    @GetMapping("/port/query")
    public String portQuery(@RequestParam(value = "portId") String portId) {
        OSClientV3 os = Auth.getOS();
        Port port = os.networking().port().get(portId);
        return JSONObject.toJSONString(port);
    }

//    Cannot update read-only attribute created_at
    @GetMapping("/port/update")
    public String portUpdate() {
        OSClientV3 os = Auth.getOS();
        Port port = os.networking().port().get("2d2576fd-fa77-499c-9f57-80f9495c6b11");
        Port updatedPort = os.networking().port().update(port.toBuilder().name("port-1-1").build());
        return JSONObject.toJSONString(updatedPort);
    }

//    {
//code: 204
//success: true
//}
    @GetMapping("/port/delete")
    public String portDelete(@RequestParam(value = "portId") String portId) {
        OSClientV3 os = Auth.getOS();
        ActionResponse response = os.networking().port().delete(portId);
        return JSONObject.toJSONString(response);
    }

    @GetMapping("/router/list")
    public String routerList() {
        OSClientV3 os = Auth.getOS();
        List<? extends Router> list = os.networking().router().list();
        return JSONObject.toJSONString(list);
    }

//     Attribute 'routes' not allowed in POST
    @GetMapping("/router/create")
    public String routerCreate() {
        OSClientV3 os = Auth.getOS();
        Router router = os.networking().router().create(Builders.router()
                .name("ext_net")
                .adminStateUp(true)
                .externalGateway("f885eaf3-2879-4147-b537-dd27fa3a345e")
                .route("192.168.0.0/24", "10.20.20.1")
                .build());
        return JSONObject.toJSONString(router);
    }
}
